package tuanda.soict.firstsun.LogicPackage;

import java.util.Random;

import tuanda.soict.firstsun.DataPackage.CommonConstants;

/**
 * @author tuanda_soict_hut
 * @version 0.0.7
 * @since 7-9-2012
 */
public abstract class Unit implements Controllable, CommonConstants {

	private String name;
	private int groupID;
	// changeable properties
	private int rank;
	// position properties
	private Coordinate coordinate;
	// control properties
	private boolean isActionLeft;
	private boolean isMoveLeft;
	// modify properties
	private int tempDefense;
	private int tempAttack;
	private int tempMovement;
	private int tempAttackRange;
	// unchangeable properties
	private int minAttack;
	private int maxAttack;
	private int defense;
	private int movement;
	private int attackRange;
	private int type;
	private int goldRequire;
	private int dataID;

	public Unit(String nam, int groID, int ran, int minAtk, int maxAtk,
			int def, int mov, int range, int typ, int gold, int x, int y,
			int dataID) {
		setName(nam);
		setGroupID(groID);

		setAttack(minAtk, maxAtk);
		setDefense(def);
		setMovement(mov);
		setAttackRange(range);
		setGoldRequire(gold);
		setUnitType(typ);
		setDataID(dataID);

		setRank(ran);
		setCoordinate(x, y);

		setTempDefense(0);
		setTempAttack(0);
		setTempMovement(0);
		setTempAttackRange(0);

		setActionLeft(true);
		setMoveLeft(true);
	}

	public final int getDataID() {
		return this.dataID;
	}

	public final void setDataID(int id) {
		this.dataID = id;
	}

	public final int getUnitType() {
		return this.type;
	}

	public final void setUnitType(int typ) {
		this.type = typ;
	}

	public final int getGoldRequire() {
		return this.goldRequire;
	}

	public final void setGoldRequire(int gold) {
		this.goldRequire = gold;
	}

	public final int getLocationX() {
		return this.coordinate.getLocationX();
	}

	public final int getLocationY() {
		return this.coordinate.getLocationY();
	}

	public final Coordinate getCoordinate() {
		return this.coordinate;
	}

	public final void setCoordinate(int x, int y) {
		this.coordinate = new Coordinate(x, y);
	}

	public final void setCoordinate(Coordinate destination) {
		if (destination != null) {
			this.coordinate = destination;
		}
	}

	public final int getRank() {
		return this.rank;
	}

	public final void setRank(int ran) {
		this.rank = ran;
	}

	public final int getAttackRange() {
		return this.attackRange;
	}

	public final void setAttackRange(int range) {
		this.attackRange = range;
	}

	public final boolean isInAttackRange(int x, int y) {
		if ((Math.abs(getLocationX() - x) + Math.abs(getLocationY() - y)) <= getTotalAttackRange()) {
			return true;
		} else {
			return false;
		}
	}

	public final int getMinAttack() {
		return this.minAttack;
	}

	public final int getMaxAttack() {
		return this.maxAttack;
	}

	public final int getNormalDamage() {
		return ((getTotalMaxAttack() + getTotalMinAttack()) / 2);
	}

	public final int getDamage() {
		Random dam = new Random();
		int minAtk = getTotalMinAttack();
		int maxAtk = getTotalMaxAttack();
		int damage = minAtk + dam.nextInt(maxAtk - minAtk + 1);
		return damage;
	}

	public final void setAttack(int minAtk, int maxAtk) {
		this.minAttack = minAtk;
		this.maxAttack = maxAtk;
	}

	public final int getMovement() {
		return this.movement;
	}

	public final void setMovement(int mov) {
		this.movement = mov;
	}

	public final boolean isInMovementRange(int x, int y) {
		if ((Math.abs(getLocationX() - x) + Math.abs(getLocationY() - y)) <= getTotalMovement()) {
			return true;
		} else {
			return false;
		}
	}

	public final int getDefense() {
		return this.defense;
	}

	public final void setDefense(int def) {
		this.defense = def;
	}

	public final boolean isMoveLeft() {
		return this.isMoveLeft;
	}

	public final void setMoveLeft(boolean isMove) {
		isMoveLeft = isMove;
	}

	public final boolean isActionLeft() {
		return this.isActionLeft;
	}

	public final void setActionLeft(boolean isAction) {
		isActionLeft = isAction;
		if (isAction == false) {
			isMoveLeft = false;
		}
	}

	@Override
	public final String getName() {
		return this.name;
	}

	@Override
	public final void setName(String nam) {
		this.name = nam;
	}

	public final int getGroupID() {
		return this.groupID;
	}

	public final void setGroupID(int groID) {
		this.groupID = groID;
	}

	public final int getTotalDefense() {
		int total = getDefense() + getTempDefense();
		if (total > 0) {
			return total;
		} else {
			return 0;
		}
	}

	public final int getTotalAttackRange() {
		int total = getAttackRange() + getTempAttackRange();
		if (total > 0) {
			return total;
		} else {
			return 0;
		}
	}

	public final int getTotalMovement() {
		int total = getMovement() + getTempMovement();
		if (total > 0) {
			return total;
		} else {
			return 0;
		}
	}

	public final int getTotalMinAttack() {
		int total = getMinAttack() + getTempAttack();
		if (total > 0) {
			return total;
		} else {
			return 0;
		}
	}

	public final int getTotalMaxAttack() {
		int total = getMaxAttack() + getTempAttack();
		if (total > 0) {
			return total;
		} else {
			return 0;
		}
	}

	public final int getTempDefense() {
		return this.tempDefense;
	}

	public final void setTempDefense(int tempDef) {
		this.tempDefense = tempDef;
	}

	public final int getTempAttack() {
		return this.tempAttack;
	}

	public final void setTempAttack(int tempAtk) {
		this.tempAttack = tempAtk;
	}

	public final int getTempMovement() {
		return this.tempMovement;
	}

	public final void setTempMovement(int tempMov) {
		this.tempMovement = tempMov;
	}

	public final int getTempAttackRange() {
		return this.tempAttackRange;
	}

	public final void setTempAttackRange(int range) {
		this.tempAttackRange = range;
	}
}
